#include "bibitem.h"
#include <QString>
#include <QDebug>

bibItem::bibItem() {

}

bibItem::bibItem(QString const &s) {
    readContent(s);
}

bibItem::~bibItem() {}

/**
 * @brief 读取文献信息，存储到content变量中
 * @param s: bib字符串
 */
void bibItem::readContent(const QString &s) {
    content.clear();
    int pos = 0;
    this->citationKey = getCitationKey(s);
    this->content["citationKey"] = this->citationKey;

    this->type = getType(s);
    while(pos < int(s.size()-3)) {
        QString key = getKey(s, pos), value = getValue(s, pos);
        this->content[key] = value;
    }
}

QString bibItem::getType(QString const &s) {
#ifdef TODO
    int atpos = s.indexOf("@");
    int i;
    for(i = atpos; i<s.size(); ++i) {
        if(s[i].isLetter()) i++;
    }
    QString cikey = s.mid(atpos, i-1);
#else
    Q_UNUSED(s);
    QString cikey = "ARTICLE";
#endif
    return cikey;
}

/**
 * @brief 获取citationKey
 * @param s: bib字符串
 * @return citationKey
 */
QString bibItem::getCitationKey(const QString &s) {
    int starting = s.indexOf("{")+1;
    int i = starting;
    while(s[i].isLetterOrNumber()) i++;
    QString type = s.mid(starting, i);
    return type;
}

/**
 * @brief 获取一个条目的key信息
 * @param s: bib字符串
 * @param from: 获取信息的起始下标
 * @return key
 */
QString bibItem::getKey(QString const & s, int &from) {
    int pos = from;
    while(pos < s.size() && s[pos]!=',') pos++;
    pos++; // one past comma
    while(pos < s.size() && s[pos]==' ') pos++;
    int prev = pos;
    while(pos < s.size() && s[pos].isLetter()) pos++;
    from = pos;
    return s.mid(prev, pos-prev).toLower();
}

/**
 * @brief 获取一个条目的value信息
 * @param s: bib字符串
 * @param from: 获取信息的起始下标
 * @return value
 */
QString bibItem::getValue(QString const & s, int &from) {
    int pos = s.indexOf('{', from) + 1;
    int left = 1;
    int prev = pos;
    while(pos < s.size() && left > 0) {
        if(s[pos]=='{') left++;
        else if(s[pos]=='}') left--;
        pos++;
    }
    pos--;
    QString mid = s.mid(prev, pos-prev);
    from = pos;
    return mid;
}

/**
 * @brief 根据content中的信息生成bib字符串
 * @return 生成的bib字符串
 */
QString bibItem::toString() {
    QString str = QString("@ARTICLE{%1,").arg(citationKey);
    for(auto it = content.cbegin(); it!=content.cend(); ++it) {
        if(not it.key().isEmpty()) {
            QString buf = "%1 = {%2},\n";
            buf = buf.arg(it.key(), it.value());
            str += buf;
        }
    }
    str += "}\n";
    return str;
}

/**
 * @brief 重载下标运算符，封装content，返回对应数据项的信息
 * @param 要获取的数据项信息的key
 * @return 数据项信息的value
 */
QString bibItem::operator[](const QString &entry) {
    return content[entry];
}

QString bibItem::exportBib() {
    // TODO: Implement
    return QString();
}

